package web.server.utils;

import cn.hutool.core.util.HexUtil;
import lombok.extern.slf4j.Slf4j;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Objects;

/**
 * 字节操作帮助类
 * @author guochuang
 * @date 2022/01/20 15:38:00
 */
@Slf4j
public class ByteHelper {



    public static byte[] hexStringToByteArray(String hexString, String spaceMark) {

        StringBuilder sb = new StringBuilder();
        if (hexString.contains(spaceMark)) {
            for (String s : hexString.split(spaceMark)) {
                sb.append(s.trim());
            }
            hexString = sb.toString();
        }
        return HexUtil.decodeHex(hexString);
    }

    public static byte[] hexStringToByteArray(String hexString) {

        if (hexString.contains(", ")) {
            return hexStringToByteArray(hexString, ", ");
        } else if (hexString.contains(",")) {
            return hexStringToByteArray(hexString, ",");
        } else if (hexString.contains(" ")) {
            return hexStringToByteArray(hexString, " ");
        }
        return HexUtil.decodeHex(hexString);
    }

    public static String bytesToHexString(byte[] src, String spaceMark) {

        return Objects.requireNonNull(bytesToHexString(src)).replace(" ", spaceMark);
    }

    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte b : src) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv).append(" ");
        }
        return stringBuilder.substring(0, stringBuilder.toString().length() - 1);
    }

    public static String byteToHexString(byte src) {

        return bytesToHexString(new byte[]{src});
    }

    public static byte[] byteMergerToNew(byte[]... src) {

        int len = 0;
        for (byte[] bytes : src) {
            len += bytes.length;
        }
        byte[] dest = new byte[len];
        int length = 0;
        for (byte[] bytes : src) {
            appendByte(bytes, dest, length);
            length += bytes.length;
        }
        return dest;
    }

    public static void byteMergerToDest(byte[] dest, byte[]... src) {

        int length = 0;
        for (byte[] bytes : src) {
            appendByte(bytes, dest, length);
            length += bytes.length;
        }
    }

    public static void appendByte(byte[] src, byte[] dest, int destPos) {
        System.arraycopy(src, 0, dest, destPos, src.length);
    }

    public static byte[] substring(byte[] src, int beginIndex, int endIndex) {

        byte[] dest = new byte[endIndex - beginIndex];
        System.arraycopy(src, beginIndex, dest, 0, endIndex - beginIndex);
        return dest;
    }

    /**
     * 二进制字符串解码为byte
     * @param byteStr   二进制字符串
     * @return          byte
     */
    public static byte decodeBinaryString(String byteStr) {
        int re, len;

        if (null == byteStr) {
            return 0;
        }
        len = byteStr.length();

        if (len != 4 && len != 8) {
            return 0;
        }

        if (len == 8) {// 8 bit处理
            if (byteStr.charAt(0) == '0') {// 正数
                re = Integer.parseInt(byteStr, 2);
            } else {// 负数
                re = Integer.parseInt(byteStr, 2) - 256;
            }
        } else {//4 bit处理
            re = Integer.parseInt(byteStr, 2);
        }

        return (byte) re;
    }

    public static int byteToInt10(byte temp) {
        return (int) temp;
    }

    /**
     * int类型 10进制转16进制
     * @param temp    参数
     * @return          0xxx
     */
    public static int int10To16(int temp) {
        return Integer.parseInt(Integer.toHexString(temp), 16);
    }

    /**
     * string类型 10进制转16进制
     * @param temp    参数
     * @return          0xxx
     */
    public static int string10To16(String temp) {
        return int10To16(Integer.parseInt(temp));
    }

    /**
     * string类型 16进制转10进制
     * @param temp  参数
     * @return      10进制字符串
     */
    public static String string16To10(String temp) {return new BigInteger(temp, 16).toString(10);}

    public static int string16ToInt10(String temp) {
        return Integer.parseInt(string16To10(temp));
    }

    public static byte[] timestamp2bytes(long l) {
        // 精确到秒钟
        return int2Bytes((int) (l / 1000));
    }

    public static byte[] int2Bytes(int n) {

        return ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(n).array();
    }

    public static void console(String var1, byte[] bytes) {
        log.info(var1 + " " + ByteHelper.bytesToHexString(bytes));
    }


}
